package com.njmaomao.gj.pyot.domain.wechat.wechatapi;

import com.njmaomao.gj.pyot.common.ResponseCode;
import com.njmaomao.gj.pyot.common.Utils;
import com.njmaomao.gj.pyot.common.XmlUtil;
import com.njmaomao.gj.pyot.common.exception.SystemBizFail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;

public abstract class ApiService {

    protected Logger log = LoggerFactory.getLogger(ApiService.class);

    protected abstract RestTemplate getRestTemplate();

    protected  <R, T> R post(String url, T t, Class<R> clazz) {

        return post(url, t, clazz, getRestTemplate(), Optional.empty());

    }

    protected  <R, T> R post(String url, T t, Class<R> clazz, RestTemplate restTemplate) {

        return post(url, t, clazz, restTemplate, Optional.empty());

    }

    protected  <R, T> R post(String url, T t, Class<R> clazz, RestTemplate restTemplate, Optional<Consumer<String>> validConsumerOpt) {

        long start = System.currentTimeMillis();

        String reqStr = XmlUtil.objectToXml(t);

        log.info("post wechat-pay url:{}, req:{}, reqStr:{}", url, Utils.toJson(t), reqStr.replaceAll("(\n)|(\\s+)", ""));

        String respStr = restTemplate.postForObject(url, reqStr, String.class);

        R resp = XmlUtil.xml2Bean(respStr, clazz);

        log.info("post wechat-pay url:{}, resp:{}, spent: {}ms, respStr: {}", url, Utils.toJson(resp), System.currentTimeMillis() - start, respStr.replaceAll("(\n)|(\\s+)", ""));

        ApiResp apiResp = (ApiResp) resp;
        if(!apiResp.isCallSuccess()) {
            SystemBizFail.happen(ResponseCode.PAYTO.WECHAT_CALL_ERROR, apiResp.errDesc());
        }

        validConsumerOpt.ifPresent(validConsumer -> validConsumer.accept(respStr));

        return resp;

    }

    protected  <R, T> R get(String url, T t, Class<R> clazz, Consumer<String> validConsumer) {

        long start = System.currentTimeMillis();

        Map<String, String> reqMap = XmlUtil.xmltoMap(XmlUtil.objectToXml(t));
        String paramStr = reqMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));

        log.info("post wechat-pay url:{}, paramStr:{}, req:{}", url, paramStr, Utils.toJson(t));

        String respStr = getRestTemplate().getForObject(url + "?" + paramStr, String.class);

        R resp = XmlUtil.xml2Bean(respStr, clazz);

        log.info("post wechat-pay url:{}, resp:{}, spent: {}ms, respStr: {}", url, Utils.toJson(resp), System.currentTimeMillis() - start, respStr);

        ApiResp apiResp = (ApiResp) resp;
        if(!apiResp.isCallSuccess()) {
            SystemBizFail.happen(ResponseCode.PAYTO.WECHAT_CALL_ERROR, apiResp.errDesc());
        }

        validConsumer.accept(respStr);

        return resp;

    }

}
